//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#include "PatternWeight.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <fstream>
#include <iostream>
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
using namespace std;
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#define MAX_SIZE 500000
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
PatternWeight::PatternWeight () {

  this->type     = new String ();
  this->pattern  = new String ();
  this->weight   = 0;
  
  this->toString = new String ();

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
PatternWeight::PatternWeight (const PatternWeight& patternWeight) {

  this->type     = new String (patternWeight.type);
  this->pattern  = new String (patternWeight.pattern);
  this->weight   = patternWeight.weight;

  this->toString = new String (patternWeight.toString);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
PatternWeight::PatternWeight (const PatternWeight* patternWeight) {

  this->type     = new String (patternWeight->type);
  this->pattern  = new String (patternWeight->pattern);
  this->weight   = patternWeight->weight;

  this->toString = new String (patternWeight->toString);
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
PatternWeight::~PatternWeight () {

  if (this->type)     delete this->type;
  if (this->pattern)  delete this->pattern;
  if (this->toString) delete this->toString;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void PatternWeight::Type (String* type) {

  if (type)
    *(this->type) = *type;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void PatternWeight::Pattern (String* pattern) {

  if (pattern)
    *(this->pattern) = *pattern;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void PatternWeight::Weight (float weight) {

  this->weight = weight;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* PatternWeight::Type (void) {

  return this->type;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* PatternWeight::Pattern (void) {

  return this->pattern;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
float PatternWeight::Weight (void) {

  return this->weight;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool PatternWeight::ReadFromString (String* data) {

  if (!data) return false;
  
  return this->ReadFromString(data->Out());

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool PatternWeight::ReadFromString (char* line) {
  
  if (!line) return false;
  
  char* parts = NULL;

  if ((strstr(line, "*") && strstr(line, "+")) || (strstr(line, "*") && !strstr(line, "+"))) {
    
    if (!(parts = strtok(line, " +*\n\t\r"))) return false;
    this->weight = atof(parts);
    
    if (!(parts = strtok(NULL, " +*\n\t\r"))) return false;
    if (!(parts = strtok(NULL, " +*\n\t\r"))) return false;
    
    if (!strncmp(parts, "Seq", 3)) {
      this->pattern->In(parts + 4);
      this->type->In("Seq");
    }
    else if (!strncmp(parts, "CH", 2)) {
      this->pattern->In(parts + 3);
      this->type->In("CH");
    }
    else if (!strncmp(parts, "PH", 2)) {
      this->pattern->In(parts + 3);
      this->type->In("PH");
    }
    else if (!strncmp(parts, "SS", 2)) {
      this->pattern->In(parts + 3);
      this->type->In("SS");
    }
    else if (!strncmp(parts, "MT", 2)) {
      this->pattern->In(parts + 3);
      this->type->In("MT");
    }
    else {
      this->pattern->In(parts);
      this->type->In("");
    }  
    
  }
  else if (!strstr(line, "*") && strstr(line, "+")) {
    
    if (!(parts = strtok(line, " +*\n\t\r"))) return false;
    
    this->weight = atof(parts);
    this->pattern->In("");
    this->type->In("Correction");
    
  }
  else return false;
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
PatternWeight PatternWeight::operator= (const PatternWeight& patternWeight) {

  *(this->type)     = *(patternWeight.type);
  *(this->pattern)  = *(patternWeight.pattern);
  
  this->weight      = patternWeight.weight;

  *(this->toString) = *(patternWeight.toString);
  
  return *this;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
